Description

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

 

Solution

题目要求找数组中所有出现次数多于1/3的元素。并希望算法的时间复杂度为O(n)空间复杂度为O(1)。

初步想来难以以题中要求的复杂度完成,但可以发现隐含条件是,出现次数多于1/3的值最多只有两个(1个或2个)。因此,可以通过设定两个备选值的方式来确定哪两个(也可能是一个)值符合条件。

为什么是设定两个备选而不是一个或其他?

设定两个备选的含义是将数组中的元素看做是3类,分别是:1.与备选值1相等的值;2.与备选值2相等的值;3.与备选值1和2都不相等的值。

 

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class Solution {
public:
vector<int> majorityElement(vector<int>& nums)
{
int a = 0, b = 0;
int cnta = 0, cntb = 0;
for(int i = 0; i < (int)nums.size(); i++)
{
bool flag = false;
if(cnta == 0)
{
if(cntb != 0 && b == nums[i])
{
cntb++;
flag = true;
}
else
{
a = nums[i];
cnta = 1;
flag = true;
}
}
else
{
if(a == nums[i])
{
cnta++;
flag = true;
}
else if(cntb != 0 && b == nums[i])
{
cntb++;
flag = true;
}
else if(cntb == 0)
{
b = nums[i];
cntb = 1;
flag = true;
}
}
if(flag == false)
{
cnta--;
cntb--;
}
}
cnta = cntb = 0;
for(int i = 0; i < (int)nums.size(); i++)
{
if(nums[i] == a) cnta++;
if(nums[i] == b) cntb++;
}
vector<int> ret;
if(cnta > (int)nums.size() / 3) ret.push_back(a);
if(b != a && cntb > (int)nums.size() / 3 ) ret.push_back(b);
return ret;
}
};